package fon.rm2.server.tcpserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class Server extends Thread 
{
	
	Boolean end = false;
	ServerSocket ss = null;
	Socket s = null;
	String st = null;
	BufferedReader input;
	PrintWriter output;
	boolean firstAndOnlyClient = false;
	private boolean pauseMe = true, stopMe = false;
	
	// Trebalo bi napraviti neki jednostavan protokol, tipa, kada se klijent konektuje, server postalje "nesto" na sta
	// klijent odgovori "nechim" (npr. ACK). Ukoliko odgovor od klijenta ne stigne za neko razumno vreme, treba pretpostaviti
	// problem sa klijentom i eventualno ga izbaciti iz liste, ili ako podrzavamo samo jednog klijenta, onda ga treba diskonektovati.
	// Generalno tu komunikaciju kada server posalje nesto klijentu, pa ceka da mu ovaj odgovori, bi mozda trebalo resiti u jos jednoj,
	// dodatnoj, niti, koja bi se bavila samo sa input.readLine(); cisto da server ne bi stajao zakucan, dok klijent ne odgovori.
	// Mozda ne bi bilo lose, da se ukoliko se bude podrzavalo vise klijenata, uvek za svakoga pravi zasebna "komunikaciona" nit u tim
	// trenucima, kada se ceka na odgovor, koja bi odmah zatim (kada odgovor stigne) bila i unistena. Treba razmisliti...
	
	// Ovo iznad je totalno pogresno, odnosilo se na to da je Android klijent, a ovo server. Android zapravo nije klijent, nego DEO
	// servera, tako da zaista i postoji samo jedan Android. U svakom slucaju bi trebalo ovo sve uraditi asinhrono, da ne bude da, ukoliko 
	// stigne vise zahteva u vremenskim intervalima male razlike, Android ne moze da postigne sve to, jer radi na nekom "prethodnom" zahtevu,
	// pa dodje do velikog kasnjenja (verovatno bi se i akumuliralo). Upravo zato sto postoji samo jedan Android (sistem slanja sms-ova), 
	// i vise PRAVIH klijenata (ATM uredjaji, simuliramo ih hardverom), trebalo bi osmisliti sistem sesije, odnosno nekog session ID-a, 
	// na osvnovu kog bi znali na koga se koji request (poslati SMS) odnosi. Sms bi verovatno trebalo i vremenski ograniciti, 
	// a mozda ne bi bilo lose, i sve ove transakcije cuvati u bazi. Zapravo, ne da ne bi bilo lose, mora se cuvati i u bazi.
	
	// Ako posumnjamo da nekim slucajem, ovo sve radi. Mozda ne bi bilo lose napraviti i nekoliko virtuelnih klijenata (ATM-ova), koji bi
	// simulirali ovaj nas hardver, cisto da vidimo taj konkurentni sistem rada. To njima mozemo da pokazemo a i ne moramo, ako im je bas
	// bitno da vide samo hardver.
	
	public Server()
	{
		try 
		{			
			ss = new ServerSocket(8090);
			
			if(!firstAndOnlyClient)
				s = ss.accept();
		
			firstAndOnlyClient = true;
			System.out.println("Client arrived...");
			input = new BufferedReader(new InputStreamReader(s.getInputStream()));
			output = new PrintWriter(s.getOutputStream(),true);
			
			this.start();
		}
		catch (UnknownHostException e) 
		{
			e.printStackTrace();
		}	
		catch (IOException e) 
		{
			e.printStackTrace();
		}
	}
	
	
	public void SendCommandToClient(String command)
	{
		try
		{
			if(firstAndOnlyClient)
			{
				System.out.println("OK, client connected, you can start sending commands.");
				output.println(command);
				String response = input.readLine();			// Trenutno server stoji i cheka odgovor klijenta, nakon poslate komande
				if(response.equals("ACK"))
				{
					// Klijent je primio komandu
					
					response = input.readLine();	// Ceka se odgovor klijenta sa statusom izvrsavanja poslate komande
					if(response.equals("OK"))
					{
						// Klijent je uspesno izvrsio komandu
					}
					else
					{

					}
				}
				else
				{
					
				}
			}
		else
		{
			System.out.println("Client has not been connected yet. Commands cannot be sent.");
		}
		}
		catch(Exception ex)
		{			
		}
	}
	
	
	@Override
	public void run() 
	{
		try
		{						
			
			while(!stopMe)
			{
				synchronized(this) 
				{
					while(this.pauseMe) 
					{
						wait();
					}
				}
				
				//st = input.readLine();
				//end = st.equals("q");
				//System.out.println("Echo: " + st + "\n");
				//output.println("Echo: " + st + "\n");	                  
			}		
			System.out.println("Server stopped...");
			input.close();
			output.close();
			s.close();
			ss.close();
			this.join();
		}
		catch(Exception ex)
		{		
		}
	}
	
	public synchronized void PauseServer() 
	{
		if(!pauseMe)
		{
			this.pauseMe = true;
			notifyAll();
		}
	}
	public synchronized void ResumeServer() 
	{
		if(pauseMe)
		{
			this.pauseMe = false;
			notifyAll();
		}
	}
}
